﻿#ifndef _SQLDRIVER_H_H_
#define _SQLDRIVER_H_H_

#include "udatabase/sqlutility.h"
#include "udatabase/sqlindex.h"
#include "udatabase/sqlerror.h"
#include "kernel/Referenced.h"

namespace FD{
	namespace Utility{
		namespace DB{

			class CSqlDatabase;
			class CSqlField;
			class CSqlIndex;
			class CSqlRecord;
			class CSqlResult;
			class CSqlError;
			class CSqlDriverPrivate;
			///<summary>
			///访问指定数据库的数据库驱动基类
			///</summary>
			class FD_DB_Export CSqlDriver :  public FD::Kernel::CReferenced
			{
			public:
				/// <summary>
				/// 数据库特性枚举
				/// </summary>
				enum JASDriverFeature { DF_Transactions, DF_QuerySize, DF_BLOB, DF_Unicode, DF_PreparedQueries,
					DF_NamedPlaceholders, DF_PositionalPlaceholders, DF_LastInsertId,
					DF_BatchOperations, DF_SimpleLocking, DF_LowPrecisionNumbers,
					DF_EventNotifications, DF_FinishQuery, DF_MultipleResultSets };
				/// <summary>
				///	SQL语句类型枚举
				/// </summary>
				enum JASStatementType {ST_WhereStatement, ST_SelectStatement, ST_UpdateStatement,
					ST_InsertStatement, ST_DeleteStatement };
				/// <summary>
				///	标识类型枚举
				/// </summary>
				enum JASIdentifierType { IT_FieldName, IT_TableName };
			protected:
				explicit CSqlDriver();
			public:
				///<summary>
				///析构函数
				///</summary>
				///<param name=""></param>
				///<returns></returns>
				~CSqlDriver();

				/// <summary>
				/// 返回数据库的句柄
				/// </summary>
				/// <returns>数据库句柄</returns>
				virtual FD::Kernel::Variant handle() const;
				/// <summary>
				/// 判断数据库是否支持某一特性
				/// </summary>
				/// <param name="f">数据库特性</param>
				/// <returns>如果支持返回true，否则false</returns>
				virtual bool hasFeature(FD::Utility::DB::CSqlDriver::JASDriverFeature f) const;
				///<summary>
				///当前数据库是否打开
				///</summary>
				///<param name=""></param>
				///<returns>打开返回true，否则返回false</returns>
				virtual bool isOpen() const;
				///<summary>
				///打开数据库时是否出错
				///</summary>
				///<param name=""></param>
				///<returns>打开出错返回true，否则返回false</returns>
				bool isOpenError() const;
				///<summary>
				///获取发生在数据库上面的最后的错误
				///</summary>
				///<param name=""></param>
				///<returns>包含发生在数据库上面的最后的错误信息的FD::Utility::DB::CSqlError对象</returns>
				FD::Utility::DB::CSqlError lastError() const;

				/// <summary>
				/// 判断指定数据库是否存在
				/// </summary>
				/// <param name="dbname">数据库名</param>
				/// <returns>返回True or False</returns>
				virtual bool exist(const FD::Kernel::FdUnicodeString &dbname) const;
				/// <summary>
				/// 检索数据库的指定类型的所有表名
				/// </summary>
				/// <param name="tableType">表类型</param>
				/// <returns>返回数据库的指定类型的所有表名</returns>
				virtual FD::Kernel::FdWStringArray tables(JASTableType tableType) const;
				/// <summary>
				/// 返回表的主键索引
				/// </summary>
				/// <param name="tablename">表名</param>
				/// <returns>返回对应的表的FD::Utility::DB::CSqlIndex</returns>
				virtual FD::Utility::DB::CSqlIndex primaryIndex(const FD::Kernel::FdUnicodeString &tableName) const;
				/// <summary>
				/// 返回指定表的元信息，包含各个字段信息
				/// </summary>
				/// <param name="tablename">表名</param>
				/// <returns>返回对应的表的元信息的record</returns>
				virtual FD::Utility::DB::CSqlRecord record(const FD::Kernel::FdUnicodeString &tableName) const;
				///<summary>
				///根据给定的信息打开数据库
				///</summary>
				///<param name="db">数据库名</param>
				///<param name="user">用户名</param>
				///<param name="password">密码</param>
				///<param name="host">主机名</param>
				///<param name="port">端口号</param>
				///<param name="connOpts">连接选项</param>
				///<returns>打开成功返回true,否则返回false</returns>
				virtual bool open(const FD::Kernel::FdUnicodeString& db,
					const FD::Kernel::FdUnicodeString& user ,
					const FD::Kernel::FdUnicodeString& password ,
					const FD::Kernel::FdUnicodeString& host ,
					INT32 port ,
					const FD::Kernel::FdUnicodeString& connOpts);
				/// <summary>
				/// 关闭数据库连接
				/// </summary>
				/// <param name=""></param>
				/// <returns></returns>
				virtual void close();
				/// <summary>
				/// 创建对应的FD::Utility::DB::CSqlResult对象
				/// </summary>
				/// <returns>返回driver对应的result对象</returns>
				virtual FD::Utility::DB::CSqlResult *createResult() const;
				/// <summary>
				/// 开始事务
				/// </summary>
				/// <returns>成功返回true，失败返回false</returns>
				virtual bool beginTransaction();
				/// <summary>
				/// 提交事务
				/// </summary>
				/// <returns>成功返回true，失败返回false</returns>
				virtual bool commitTransaction();
				/// <summary>
				/// 撤销事务
				/// </summary>
				/// <returns>成功返回true，失败返回false</returns>
				virtual bool rollbackTransaction();
				///<summary>
				///根据所给参数信息，构造sql语句
				///</summary>
				///<param name="type">sql语句类型</param>
				///<param name="tablename">表名</param>
				///<param name="rec">表的元信息</param>
				///<param name="preparedStatement">是否是准备语句</param>
				///<returns>sql语句</returns>
				virtual FD::Kernel::FdUnicodeString sqlStatement(FD::Utility::DB::CSqlDriver::JASStatementType type, const FD::Kernel::FdUnicodeString &tableName,
					const FD::Utility::DB::CSqlRecord &rec, bool preparedStatement) const;
				///<summary>
				///是否为需要跳过的标示符
				///</summary>
				///<param name="identifier">标示符</param>
				///<param name="type">标示符类型</param>
				///<returns>是需要跳过的标示符返回true,否则返回false</returns>
				virtual bool isIdentifierEscaped(const FD::Kernel::FdUnicodeString &identifier, FD::Utility::DB::CSqlDriver::JASIdentifierType type) const;
				///<summary>
				///跳过标示符
				///</summary>
				///<param name="identifier">标示符</param>
				///<param name="type">标示符类型</param>
				///<returns>跳过标示后的字符串</returns>
				virtual FD::Kernel::FdUnicodeString escapeIdentifier(const FD::Kernel::FdUnicodeString &identifier, FD::Utility::DB::CSqlDriver::JASIdentifierType type) const;
				///<summary>
				///格式化字段值
				///</summary>
				///<param name="field">字段</param>
				///<param name="trimStrings">是否截断filed尾部的所有空白字符</param>
				///<returns>格式化后的字符串</returns>
				virtual FD::Kernel::FdUnicodeString formatValue(const FD::Utility::DB::CSqlField& field, bool trimStrings = false) const;
				///<summary>
				///设置当前数据库的精度
				///</summary>
				///<param name="precisionPolicy">精度</param>
				///<returns></returns>
				void setNumericalPrecisionPolicy(JASNumericalPrecisionPolicy precisionPolicy);
				///<summary>
				///获取当前数据库的精度
				///</summary>
				///<param name=""></param>
				///<returns>精度值</returns>
                JASNumericalPrecisionPolicy numericalPrecisionPolicy() const;

			protected:
				/// <summary>
				/// 设置是否打开
				/// </summary>
				/// <returns></returns>
				virtual void setOpen(bool o);
				/// <summary>
				/// 设置是否打开错误
				/// </summary>
				/// <returns></returns>
				virtual void setOpenError(bool e);
				/// <summary>
				/// 设置最后的出错信息
				/// </summary>
				///<param name="e">错误信息</param>
				/// <returns></returns>
				virtual void setLastError(const FD::Utility::DB::CSqlError& e);

			private:
				CSqlDriverPrivate* m_private;

			private:
				C_DISABLE_COPY(CSqlDriver)
			};

		} // namespace Database
	} 
} 

#endif //_SQLDRIVER_H_H_

